package org.fixies.utils;

import org.fixies.resource.ClasspathResourceLoader;
import org.fixies.resource.ResourceLoader;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;


/**
 * プロパティ管理クラス
 *
 * @author Kawasaki
 */
public final class PropertyManager {

    /** プロパティファイルのパス */
    private static final String[] INITIAL_PROPS_PATH = {"/fixies.properties"};

    /** プロパティ */
    private static Properties props__;

    static {
        initialize();
    }

    /** デフォルトコンストラクタ */
    private PropertyManager() {
    }

    /**
     * 必須プロパティを取得する。
     *
     * @param key キー
     * @return 値
     * @throws UnexpectedProblemException キーに対応するプロパティが存在しない時
     */
    public static String getPropertyRequired(String key) {
        String value = getProperty(key);
        if (value == null) {
            throw new UnexpectedProblemException("Can't get property. key=[", key, "]");
        }
        return value;
    }

    /**
     * プロパティを取得する。
     *
     * @param key キー
     * @return 値
     */
    public static String getProperty(String key) {
        return props__.getProperty(key);

    }
    /**
     * プロパティを取得する。
     *
     * @param key キー
     * @param defaultValue 取得できない場合のデフォルト値
     * @return 値
     */
    public static String getProperty(String key, String defaultValue) {
        return props__.getProperty(key, defaultValue);
    }

    /**
     * プロパティファイルを複数読み込む。
     *
     * @param propFilePaths プロパティファイルのパス
     * @return プロパティ
     */
    private static void loadProperties(Properties props, String... propFilePaths) {

        ResourceLoader resourceLoader = new ClasspathResourceLoader();
        for (String propFilePath : propFilePaths) {
            try {
                InputStream is = resourceLoader.loadResource(propFilePath);
                props.load(is);
            } catch (IOException e) {
                throw new UnexpectedProblemException(e,
                        "Can't load resource. resource name =[", propFilePath, "]");
            }
        }
    }

    /**
     * 初期化を行う。
     */
    public static synchronized void initialize() {
        Properties props = new Properties();
        loadProperties(props, INITIAL_PROPS_PATH);

        String otherProps = props.getProperty("fixies.include.properties");
        loadProperties(props, otherProps.split("\\s*,\\s*"));
        props__ = props;
    }
}
